package com.qiangesoft.oss.strategy;

import com.qiangesoft.oss.config.FileStoreProperties;
import com.qiangesoft.oss.config.StrategyFactory;
import com.qiangesoft.oss.constant.FileStoreTypeEnum;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 七牛云策略实现
 *
 * @author qiangesoft
 * @date 2024-05-13
 */
@Slf4j
@RequiredArgsConstructor
@Service
@ConditionalOnProperty(prefix = "oss", name = "type", havingValue = "qiniu")
public class QiniuStrategyImpl implements FileStrategy {

    private Auth auth;

    private BucketManager bucketManager;

    private UploadManager uploadManager;

    public QiniuStrategyImpl(FileStoreProperties fileStoreProperties) {
        Configuration cfg = new Configuration(Region.region2());
        this.auth = Auth.create(fileStoreProperties.getAccessKey(), fileStoreProperties.getSecretKey());
        this.bucketManager = new BucketManager(this.auth, cfg);
        this.uploadManager = new UploadManager(cfg);
    }

    @Override
    public boolean existsCatalog(String catalog) throws Exception {
        return this.listCatalogs().contains(catalog);
    }

    @Override
    public void createCatalog(String catalog) throws Exception {
        if (!this.existsCatalog(catalog)) {
            bucketManager.createBucket(catalog, null);
        }
    }

    @Override
    public List<String> listCatalogs() throws Exception {
        return Arrays.asList(bucketManager.buckets());
    }

    @Override
    public void removeCatalog(String catalog) throws Exception {
        bucketManager.delete(catalog, null);
    }

    @Override
    public String uploadFile(String catalog, MultipartFile file) throws Exception {
        // 参数校验
        Assert.notNull(catalog, "bucketName is not blank");
        Assert.notNull(file, "file is not null");

        // 判断存储桶是否存在
        createCatalog(catalog);

        // 文件名
        String filename = file.getOriginalFilename();

        // 上传
        String upToken = auth.uploadToken(catalog);
        Response response = uploadManager.put(file.getInputStream(), filename, upToken, null, null);
        return catalog + SLASH + filename;
    }

    @Override
    public void removeFile(String catalog, String fileName) throws Exception {
        BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
        batchOperations.addDeleteOp(catalog, fileName);
        bucketManager.batch(batchOperations);
    }

    @Override
    public void removeFiles(String catalog, List<String> fileNames) throws Exception {
        BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
        batchOperations.addDeleteOp(catalog, fileNames.toArray(new String[0]));
        Response response = bucketManager.batch(batchOperations);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        StrategyFactory.register(FileStoreTypeEnum.MINIO, this);
    }
}